/**
 *
 * © Bahadir Zeren 2011
 * bzeren@gmail.com
 * No warranties, express or implied, are made for this program.
 *
 */
package org.baatar.util;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import org.xml.sax.Attributes;

/**
 * 
 * 
 * @author B_ZEREN
 */
public class XMLWriter {

    private OutputStream outputStream = null;

    public OutputStream getOutputStream() throws IOException, InterruptedException, XMLStreamException {
        writer.flush();
        writer.close();
        outputStream.flush();
        Thread.sleep(10);
        outputStream.close();
        return outputStream;
    }

    private XMLEventFactory xmlEventFactory = null;
    private XMLOutputFactory outputFactory = null;
    private XMLEventWriter writer = null;
    private XMLEvent lineEnd = null;
    private XMLEvent tabIndent = null;

    private int hierarchyLevel = 0;

    public void initializeXMLFile(String fileName) throws XMLStreamException, FileNotFoundException {
        outputStream = new FileOutputStream(fileName);
        xmlEventFactory = XMLEventFactory.newInstance();
        outputFactory = XMLOutputFactory.newInstance();
        writer = outputFactory.createXMLEventWriter(outputStream);
        lineEnd = xmlEventFactory.createDTD("\n");
        tabIndent = xmlEventFactory.createDTD("\t");
        StartDocument startDocument = xmlEventFactory.createStartDocument("UTF-8", "1.0");
        writer.add(startDocument);
        writer.add(lineEnd);
    }

    public void writeLineEnd() throws XMLStreamException {
        writer.add(lineEnd);
    }

    public void increaseIndent() {
        hierarchyLevel++;
    }

    public void decreaseIndent() {
        hierarchyLevel--;
    }

    public void writeIndent() throws XMLStreamException {
        for (int i = 0; i < hierarchyLevel; i++)
            writer.add(tabIndent);
    }

    public Attribute generateAttribute(String name, String value) {
        return xmlEventFactory.createAttribute(name, value);
    }

    @SuppressWarnings("unchecked")
    public void startTag(String arg0, String arg1, String arg2, Attributes attributes) throws XMLStreamException { 

        StartElement startElement = null;

        if (attributes == null) {
            startElement = xmlEventFactory.createStartElement(arg0, arg1, arg2, null, null);
        } else {

            ArrayList<Attribute> attributeList = new ArrayList<Attribute>();
            ArrayList<String> valueList = new ArrayList<String>();

            for (int i = 0; i < attributes.getLength(); i++) {
                attributeList.add(generateAttribute(attributes.getQName(i), attributes.getValue(i)));
            }

            startElement = xmlEventFactory.createStartElement(arg0, arg1, arg2, 
                                                                attributeList.iterator(),
                                                                valueList.iterator());
        }
        writeIndent();
        writer.add(startElement);
    }

    public void addCharacters(String content) throws XMLStreamException {
        Characters characters = xmlEventFactory.createCharacters(content);
        writer.add(characters);
    }

    public void startTagWithAttributeList(String arg0, String arg1, String arg2,
                            ArrayList<Attribute> attributeList) throws XMLStreamException {

        StartElement startElement = null;

        if (attributeList == null) {
            startElement = xmlEventFactory.createStartElement(arg0, arg1, arg2, null, null);
        } else {
            ArrayList<String> valueList = new ArrayList<String>();

            startElement = xmlEventFactory.createStartElement(arg0, arg1, arg2,
                                                                attributeList.iterator(),
                                                                valueList.iterator());
        }
        writeIndent();
        writer.add(startElement);
    }

    public void endTag(String arg0, String arg1, String arg2) throws XMLStreamException {
        EndElement endElement = xmlEventFactory.createEndElement(arg0, arg1, arg2);
        writer.add(endElement);
        writer.add(lineEnd);
    }
}
